/**
	Jarviscript by Javis V. Pérez from Dominican Republic
	Created someday of 2010
	Inspired by all those greats frameworks!
	Thank you jQuery, Mootools, dojo, prototype
	http://jarviscript.googlecode.com
	open source under GNU license
**/

//Codigos prototypes
String.prototype.trim = function() {
						   return this.replace(/^\s+|\s+$/g,"");
						}
String.prototype.ltrim = function() {
						   return this.replace(/^\s+/g,"");
						}
String.prototype.rtrim = function() {
						   return this.replace(/\s+$/g,"");
						}

Array.prototype.flatten = function(){
							   var flat = [];
							   for (var i = 0, l = this.length; i < l; i++){
								   var type = Object.prototype.toString.call(this[i]).split(' ').pop().split(']').shift().toLowerCase();
								   if (type) { flat = flat.concat(/^(array|collection|arguments|object)$/.test(type) ? flatten.call(this[i]) : this[i]); }
							   }
							   return flat;
							};

Array.prototype.sortNum = function(order) { //order = ASC, DESC
								if(order.toLowerCase() == "ASC"){
								   return this.sort(function (a,b) { return a-b; });
								} else {
								   return this.sort(function (a,b) { return b-a; });
								}
							}

Array.prototype.has = (!Array.indexOf ? function(o) {
												var l = this.length + 1;

												while (l -= 1) {
													if ((this[l - 1]).toString() === o.toString()) {
														return true;
													}
												}

												return false;

									  } : function (o){
												return (this.indexOf(o) !== -1);
					});
Object.prototype.each = function(callback) {
							var name, i = 0,
							length = this.length,
							isObj = length === undefined || (typeof(this)=="function");
							
							if ( isObj ) {
								for ( name in this ) {
									if ( callback.call( this[ name ], this[ name ], name ) === false ) {
										break;
									}
								}
							} else {
								for ( var value = this[0]; i < length && callback.call( value, value, i ) !== false; value = this[++i] ) {}
							}
							
							return this;
						}
Array.prototype.each = Object.each;
if(!Object.keys) Object.keys = function(o){
									var ret=[],p;
									for(p in o) if(Object.prototype.hasOwnProperty.call(o,p)) ret.push(p);
									return ret;
								}
//Empieza el Jarvis!
var jarvis = {
	get: function(sel, context){
			context = (typeof(context) != "object" ? document : jarvis.get(context));
			
			if (typeof(sel) == "object"){
				if(!sel.orig) sel.orig = {};
				return jarvis.extend(sel, jarvis);
			}

			r = Sizzle(sel, context);

			if(r.length == 1){
				r = jarvis.extend(r[0], jarvis);
				if(!r.orig) r.orig = {};
			} else {
				r.each(function(v, i){
					if(!sel.orig) sel.orig = {};
					r[i] = jarvis.extend(r[i], jarvis);
					if(!r[i].orig) r[i].orig = {};
				});
			}
			return r;
		 },

	 toDOM: function(html){
			var returnElements = [];
			var div = document.createElement('div');
			div.innerHTML = html;
			var nodes = div.childNodes;
			nodes.each(function(el){
							returnElements.push(jarvis.extend(el, jarvis));
					});
			returnElements[0].orig = {};
			return returnElements[0];
	 },

	ready: function(fn) {
				if(document.addEventListener) {	//W3C
					document.addEventListener("DOMContentLoaded", fn, false);
				} else { //IE -- From the great method in: http://www.javascriptkit.com/dhtmltutors/domready.shtml
						if (document.all && !window.opera){ //Crude test for IE
						//Define a "blank" external JavaScript tag
						  document.write('<script type="text/javascript" id="contentloadtag" defer="defer" src="javascript:void(0)"><\/script>')
						  var contentloadtag=document.getElementById("contentloadtag")
						  contentloadtag.onreadystatechange = function(){
																if (this.readyState=="complete") fn()
														      }
						}
				}
			},
	isNumber: function(num) {
				return (num === +num) || (toString.call(num) === '[object Number]');
			  },

	attr: function(name, value) {
				if (!value) return this.getAttribute(name);
				this.setAttribute(name, value);
				return this;
			},

	extend: function(obj, extObj) {
				if(!extObj){
					extObj = obj;
					obj = jarvis;
				}
				if (arguments.length > 2) {
					for (var a = 1; a < arguments.length; a++) {
						extend(obj, arguments[a]);
					}
				} else {
					for (var i in extObj) {
						obj[i] = extObj[i];
					}
				}
				return obj;
			},
	
	create: function(el,opt){
				newEle = document.createElement(el);
				jarvis.extend(newEle,jarvis);
				if(typeof(opt) == "object"){
					newEle = jarvis.extend(newEle,opt);
				}
				return newEle;
			},

	insert: function(obj) {
				  if (typeof(obj) == "string") obj = jarvis.toDOM(obj);
				  return this.appendChild(obj);
			  },

	empty: function(){
				this.innerHTML = "";
				return this;
			},
	remove: function(){
				  if(!this.parentNode) return this;
				  this.parentNode.removeChild(this);
				  return jarvis;
			},

	replace: function(node){
				if(!this.parentNode) return this;
				this.parentNode.insertBefore(node,this);
				this.remove();
				return this;
			},
	wrap: function(node){
				node = jarvis.get(node);
				this.replace(node);
				node.insert(this);
				return node;
			},
	loadJs: function(src) {
				return document.write('<script type="text/javascript" src="'+src+'"></script>');
			},
	txt: function(code, html, append){
				if(arguments.length === 0){
					if (typeof(this.textContent) != 'undefined') return this.textContent;
					if (typeof(this.innerText) != 'undefined') return this.innerText;
					if (typeof(this.innerHTML) == 'string') return this.innerHTML.replace(/<[^<>]+>/g,'');
				}
				html = html || true;
				append = append || false;
				if(html === true){
					if(append) {
						this.innerHTML += code;
					} else {
						this.innerHTML = code;
					}
				} else {
					if(append){
						this.innerText += code;
					} else {
						this.innerText = code;
					}
				}
				return this;
		  },
	parent: function(){
				if (!this.parentNode) return this;
				if (arguments.length == 0) {
					return j$(this.parentNode);
				} else {
					if (this.parentNode.tagName == (arguments[0]).toUpperCase())  {
						return j$(this.parentNode);
					} else {
						j$(this.parentNode).parent(arguments[0]); 
					}
				}
			},
	next: function() {
				var n = this;
				do n = n.nextSibling;
				while (n && n.nodeType != 1);
				return j$(n);
			},
	previous: function() {
					var p = this;
					do p = p.previousSibling;
					while (p && p.nodeType != 1);
					return j$(p);
			},
	nth: function(result,dir) {
			result = result || 1;
			var num = 0;
			cur = this;
			for ( ; cur; cur = cur[dir] ) {
				if ( cur.nodeType === 1 && ++num === result ) {
					break;
				}
			}
	
			return j$(cur);
		},
	allChildren: function(){
					return this.childNodes;
				},
	find: function(selector){
			return jarvis.get(selector, this);
		  },
	toCookie: function(){
				aName = this.name || this.id || document.domain + "-jCookie";
				jCookie.create({name: aName, value: this.value});
			  },
	seek: function(val){
				if(typeof(this) == "array"){
					var returnArray = false;
					for (i=0; i<this.length; i++) {
						if (typeof(val) == 'function') {
							if (val.test(this[i])) {
								if (!returnArray) { returnArray = [] }
								returnArray.push(i);
							}
						} else
						if (this[i]===val) {
							if (!returnArray) { returnArray = [] }
							returnArray.push(i);
						}
					}
					r = returnArray;
				} else
				if(typeof(this) == "string"){
					r = this.indexOf(val);
				}
				return r;
			},
	numberFormat: function(num, places, thousands, decimals){ //Thousands separator, Decimals separator
						thousands = thousands || ",";
						decimals = decimals || ".";
						places = places || 2;
						n = new Number(num);
						num = n.toFixed(places).toString();
						var splitStr = num.split(decimals);
						var splitLeft = splitStr[0];
						var splitRight = splitStr.length > 1 ? decimals + splitStr[1] : '';
						var regx = /(\d+)(\d{3})/;
						while (regx.test(splitLeft)) {
							splitLeft = splitLeft.replace(regx, '$1' + thousands + '$2');
						}
						return splitLeft + splitRight;
				},
	
	numberUnformat: function(num) {
					   return num.replace(/([^0-9\.\-])/g,'')*1;
					}
	
};

var scripts = document.getElementsByTagName("script");
var i = scripts.length;

while(i--){
	var match = scripts[i].src.match(/(^|.*\/)jarviscript\.js$/);
	if(match){ jarvis.ROOT = match[1]; break; }
}

//parte del core, pero en archivos separados para mayor organizacion:
//Sizzle JS - Definitivamente el mejor selector de CSS - http://sizzlejs.com/
//jarvis.loadJs("sizzle.js");
//jCss - funciones relacionadas con los estilos
jarvis.loadJs(jarvis.ROOT + "/sizzle.js");
jarvis.loadJs(jarvis.ROOT + "/j$.css.js");
//jArrays - contiene todas las funciones de arrays
jarvis.loadJs(jarvis.ROOT + "/j$.arrays.js");
//jFx - contiene los efectos visuales
jarvis.loadJs(jarvis.ROOT + "/j$.fx.js");
//jEventos - todo relacionado a los eventos
jarvis.loadJs(jarvis.ROOT + "/j$.events.js");
//JEasing - easing para las animaciones
jarvis.loadJs(jarvis.ROOT + "/j$.easing.js");
//Ajax
jarvis.loadJs(jarvis.ROOT + "/j$.ajax.js");
//JToken - Hash para cache
jarvis.loadJs(jarvis.ROOT + "/j$.token.js");
//JCache
jarvis.loadJs(jarvis.ROOT + "/j$.cache.js");
//JForms - Opciones de formulario, como validar
jarvis.loadJs(jarvis.ROOT + "/j$.forms.js");
//JCookies - funciones genericas de cookies
jarvis.loadJs(jarvis.ROOT + "/j$.cookies.js");
// Alias
window.j$ = jarvis.get;